package org.jprobe.ui;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;

import org.jprobe.JProbeRuntimeException;
import org.jprobe.JavaProject;
import org.jprobe.ProjectExplorer;
import org.jprobe.junit.JUnitGenerator;
/**
 *
 * project explorer panel
 *
 * @author Hussain Al-Mutawa
 * @version 1.0
 * @since 1.0
 */
@SuppressWarnings("serial")
public class ProjectExplorerPanel extends JPanel {
	private transient final JProgressBar progressBar;
	private transient final ResultsViewerPanel resultsViewer;
	private transient final ProjectExplorer projectExplorer;
	private transient final JTextArea textArea;
	private transient String currentProject;

	private class AutoScrollTextArea extends JTextArea  {
		public void append(String text) {
			super.append(text);
			this.setCaretPosition(this.getCaretPosition()+text.length());
		}
	}

	/**
	 * gets the current project selected in the user interface
	 * @return
	 */
	protected String getCurrentProject(){
		return currentProject;
	}
	/**
	 * sets the current project
	 * @param currentProject
	 */
	protected void setCurrentProject(final String currentProject) {
		this.currentProject = currentProject;
		this.projectExplorer.setProject(currentProject);
		this.showResults();
	}

	/**
	 * initializes new project explorer panel
	 */
	public ProjectExplorerPanel() {
		super();
		//dummy implementation
		projectExplorer=new ProjectExplorer("./../colt-1.2.0");

		setBorder(BorderFactory.createEtchedBorder());
		resultsViewer=new ResultsViewerPanel();
		final JPanel panel0=new JPanel();
		final JPanel panel1=new JPanel();
		final JPanel panel2=new JPanel();
		progressBar = new JProgressBar();
		panel0.setLayout(new BorderLayout(3,3));
		panel0.add(resultsViewer,BorderLayout.NORTH);

		final JButton button1 = new JButton("Compile");
		final JButton button2 = new JButton("Copy libraries");
		final JButton button3 = new JButton("Generate test cases");
		final JButton button4 = new JButton("Generate test/coverage report");
		panel2.setLayout(new FlowLayout(FlowLayout.LEADING));
		panel2.add(button1);
		panel2.add(button2);
		panel2.add(button3);
		panel2.add(button4);


		this.setLayout(new BorderLayout(3,3));
		this.setBorder(BorderFactory.createEmptyBorder(3,3,3,3));
		this.add(panel0,BorderLayout.CENTER);
		this.add(progressBar,BorderLayout.SOUTH);
		panel0.add(panel1,BorderLayout.CENTER);
		panel0.setPreferredSize(new Dimension(0, 100));
		//panel0.setBackground(Color.WHITE);

		panel1.setLayout(new BorderLayout());
		panel1.add(panel2,BorderLayout.NORTH);

		panel2.setBorder(BorderFactory.createEtchedBorder());
		//label1.setHorizontalAlignment(SwingConstants.CENTER);

		final JTabbedPane tabbed = new JTabbedPane();

		textArea = new AutoScrollTextArea();
		textArea.setFont(new Font("monospaced",Font.PLAIN,12));
		textArea.setText("Ready\n=================================\n");
		textArea.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));

		final JScrollPane panel3 = new JScrollPane(textArea,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
		panel3.setBorder(BorderFactory.createEtchedBorder());

		panel1.add(tabbed,BorderLayout.CENTER);

		tabbed.add("Terminal", panel3);

		button1.addActionListener(new ActionListener() {
			public void actionPerformed(final ActionEvent arg0) {
				try {
					projectExplorer.compile();
				} catch (final IOException exp) {

					throw new JProbeRuntimeException(exp);
				}
			}
		});
		button2.addActionListener(new ActionListener() {
			public void actionPerformed(final ActionEvent arg0) {
				try{
					projectExplorer.addLibraryFolder();
					projectExplorer.copyLibraries();
				}catch(final IOException exp){
					throw new JProbeRuntimeException(exp);
				}
			}

		});
		button3.addActionListener(new ActionListener() {
			public void actionPerformed(final ActionEvent arg0) {
				new Thread(){
					@Override
					public void run() {
						generateTestCases();
					}
				}.start();
			}
		});
		button4.addActionListener(new ActionListener() {
			public void actionPerformed(final ActionEvent arg0) {
				throw new JProbeRuntimeException("button2 - Not implemented yet");
			}
		});
		redirectSystemStreams();
	}



	protected void generateTestCases() {
		new JUnitGenerator(new JavaProject(new File(ProjectExplorerPanel.this.getCurrentProject()))) {

			@Override
			public void progressChanged(int progress) {
				progressBar.setValue(100* progress / getTotalTransactions() );
				progressBar.revalidate();
				progressBar.invalidate();
				progressBar.repaint();
			}

			@Override
			public int getTimeOut() {
				return 5;
			}
		}.generateAll();
	}
	private void redirectSystemStreams() {
		final OutputStream out = new OutputStream() {
			@Override
			public void write(final int byteValue) throws IOException {
				textArea.append(String.valueOf((char) byteValue));

			}

			@Override
			public void write(final byte[] bytes, final int off, final int len) throws IOException {
				textArea.append(new String(bytes, off, len));
			}

			@Override
			public void write(final byte[] bytes) throws IOException {
				write(bytes, 0, bytes.length);
			}

		};

		System.setOut(new PrintStream(out, true));
		System.setErr(new PrintStream(out, true));

	}
	/**
	 * show the coverage/junit results
	 */
	public void showResults(){

		this.resultsViewer.showResults(projectExplorer);

		this.progressBar.setValue(100);
	}
}
